<?php

namespace common\traits;

use Yii;
use yii\helpers\ArrayHelper;
use common\base\ModelHttpException;
use yii\web\NotAcceptableHttpException;

/**
 * 模型处理错误特性方法
 * 
 * @author emhome <emhome@163.com>
 * @since 1.0
 */
trait ModelErrors {

    private $_errorCode = 428;

    /**
     * Adds a new error to the specified attribute.
     * @param string $attribute attribute name
     * @param array|string $error new error message
     */
    public function addError($attribute, $error = '') {
        $errorMessage = $this->formatError($error);
        Yii::error([
            'attribute' => $attribute,
            'error' => $error,
            'errorMessage' => $errorMessage,
        ], __METHOD__);
        parent::addError($attribute, $errorMessage);
    }

    /**
     * 获取错误码信息
     * @param string|array $error
     * @return string|null
     */
    protected function formatError($error) {
        if (is_string($error)) {
            return $error;
        }
        if (!is_array($error)) {
            return '';
        }
        $errorMessage = '';
        foreach ($error as $key => $vls) {
            if ($key === 'code') {
                $this->setErrorCode($vls);
                continue;
            }
            if ($key === 'message' || $key === 'msg') {
                $errorMessage .= $vls;
                continue;
            }
            if (is_numeric($vls)) {
                $this->setErrorCode($vls);
            } elseif (is_string($vls)) {
                $errorMessage .= $vls;
            }
            Yii::error([
                '$errorMessage' => $errorMessage,
            ], __METHOD__);
        }
        return $errorMessage;
    }

    /**
     * 获取错误码信息
     * @param type $code
     * @return string|null
     */
    public function setErrorCode($code) {
        if (is_numeric($code) && $code != 200) {
            $this->_errorCode = $code;
        }
    }

    /**
     * 获取错误信息
     * @param type $attribute
     * @return string|null
     */
    public function getErrorMsg($attribute = '') {
        if ($attribute) {
            return parent::getFirstError($attribute);
        }
        $errors = parent::getFirstErrors();
        if (!empty($errors)) {
            return array_shift($errors);
        }
        return null;
    }

    /**
     * 输出模型错误
     * @param string $message 错误信息
     * @param \yii\base\Model|false|null $error 扩展错误对象
     * @param integer $code 错误码
     * @throws ModelHttpException
     */
    public function dumpError($message = null, $error = null, $code = null) {
        if ($code === null) {
            $code = $this->_errorCode;
        }
        if ($error instanceof \yii\base\Model) {
            $error = $error->firstErrors;
        } else if ($error !== false) {
            $error = $this->firstErrors;
        }
        throw new ModelHttpException($message, $error, $code);
    }

    /**
     * 参数校验类错误
     */
    public function validateError($message = null, $error = null, $code = 406) {
        if ($message === null) {
            $message = '数据校验失败';
        }
        $this->dumpError($message, $error, $code);
    }

    /**
     * 数据保存类错误
     */
    public function saveError($message = null, $error = null) {
        if ($message === null) {
            $message = '数据保存失败';
        }
        $this->dumpError($message, $error, 534);
    }

    /**
     * 数据初始类错误
     */
    public function loadError($message = null) {
        if ($message === null) {
            $message = '数据初始化失败';
        }
        $this->dumpError($message, false, 416);
    }

}
